package com.xbongbong.paas.service.dynamic.crm.strategy.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.log.constant.CrmLogMemoConstant;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.service.dynamic.crm.strategy.AbstractDynamicStrategy;
import com.xbongbong.parent.interfaces.DynamicStrategy;
import com.xbongbong.paas.service.dynamic.crm.strategy.PayDynamicStrategy;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.customercommunicate.pojo.dto.DynamicDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicDeleteDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicPayDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicRefInfoDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicSaveDTO;
import com.xbongbong.pro.payment.pojo.dto.PaymentInsertBatchDTO;
import com.xbongbong.saas.domain.entity.ext.PaymentEntityExt;
import com.xbongbong.saas.enums.ProjectLogEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 应收款
 *
 *@author weijianxun
 */
@Service("payDynamicStrategyImpl")
public class PayDynamicStrategyImpl extends AbstractDynamicStrategy implements PayDynamicStrategy, DynamicStrategy {
    private final Logger LOG = LoggerFactory.getLogger(PayDynamicStrategyImpl.class);
    @Resource
    private UserModel userModel;

    private static final Map<String, Integer> refTextToLogTypeMap = new HashMap<>();

    static {
        refTextToLogTypeMap.put(PaymentEnum.CUSTOMER.getAttr(), ProjectLogEnum.CUSTOMER_REF.getSubType());
        refTextToLogTypeMap.put(PaymentEnum.CONTRACT.getAttr(), ProjectLogEnum.CONTRACT_REF.getSubType());
    }

    public static Map<String, Integer> getRefTextToLogTypeMap(){
        return Collections.unmodifiableMap(refTextToLogTypeMap);
    }

    @Override
    public List<Integer> type() {
        return Arrays.asList(XbbRefTypeEnum.PAYMENT.getCode());
    }

    @Override
    @Async("dynamicThreadPool")
    public void save(DynamicPayDTO dynamicPayDTO) {
        try {
            List<PaymentEntityExt> paymentEntityExts = dynamicPayDTO.getPaymentEntityExts();
            PaymentInsertBatchDTO paymentInsertBatchDTO = dynamicPayDTO.getPaymentInsertBatchDTO();
            String loginUserName = paymentInsertBatchDTO.getLoginUserName();
            if (StringUtil.isEmpty(loginUserName)) {
                UserEntity userEntity = userModel.getByKeyIngoreDel(paymentInsertBatchDTO.getUserId(), paymentInsertBatchDTO.getCorpid());
                loginUserName = userEntity.getName();
            }
            if (CollectionUtils.isNotEmpty(paymentEntityExts)) {
                List<DynamicDTO> dynamicDTOS = new ArrayList<>(paymentEntityExts.size());
                PaasFormEntity paasForm = getPaasForm(paymentInsertBatchDTO.getCorpid(), paymentInsertBatchDTO.getFormId(), paymentInsertBatchDTO.getBusinessType());
                for (PaymentEntityExt paymentEntityExt : paymentEntityExts) {
                    JSONObject data = paymentEntityExt.getData();
                    DynamicDTO dynamicDTO = initDynamicDTO(paymentInsertBatchDTO.getUserId(), CrmLogMemoConstant.DYNAMIC_USER_ADD, ProjectLogEnum.PAYMENT_CREATE.getSubType(),
                            DynamicDTO.initMemoHolder(loginUserName, paasForm.getName(), paymentEntityExt.getSerialNo()), paasForm, null, paymentEntityExt.getId());
                    AtomicBoolean canInsertDynamic = new AtomicBoolean(false);
                    refTextToLogTypeMap.forEach((refText, logType) -> {
                        Long refId = data.getLong(refText);
                        if (Objects.nonNull(refId)) {
                            initMainBusinessIdOrRefIdByLogType(logType, dynamicDTO, refId);
                            canInsertDynamic.set(true);
                        }
                    });
                    if(canInsertDynamic.get()) {
                        dynamicDTO.setRefBusinessType(paymentInsertBatchDTO.getBusinessType());
                        dynamicDTO.setRefName(paymentEntityExt.getSerialNo());
                        dynamicDTOS.add(dynamicDTO);
                    }
                }
                insertDynamic(dynamicDTOS, paymentInsertBatchDTO.getCorpid());
            }
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.PayDynamicStrategyImpl.save", e);
        }
    }

    @Override
    @Async("dynamicThreadPool")
    public void save(DynamicSaveDTO dynamicSaveDTO) {
        try {
            SaasFormSaveDTO saasFormSaveDTO = dynamicSaveDTO.getSaasFormSaveDTO();
            PaasFormDataEntity paasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
            saveRefUpDynamic(dynamicSaveDTO, refTextToLogTypeMap, null,
                    DynamicRefInfoDTO.initDynamicRefInfoDTO(paasFormDataEntity.getId(), saasFormSaveDTO.getBusinessType(), paasFormDataEntity.getSerialNo()), ProjectLogEnum.PAYMENT_CREATE.getSubType());
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.PayDynamicStrategyImpl.save(com.xbongbong.pro.dynamic.pojo.dto.DynamicSaveDTO)", e);
        }
    }

    @Override
    @Async("dynamicThreadPool")
    public void batchDelete(DynamicDeleteDTO dynamicDeleteDTO) {
        try {
            batchRefSaveUpDynamicByDeleteBatch(dynamicDeleteDTO, refTextToLogTypeMap, null, PaymentEnum.PAYMENT_NO.getAttr(), ProjectLogEnum.PAYMENT_DELETE.getSubType());
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.PayDynamicStrategyImpl.batchDelete", e);
        }
    }
}
